package com.itic.appbase.applications.exports;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import com.itic.appbase.applications.exports.utils.PoiHelper;
import com.itic.appbase.framework.utils.ReflectHelper;
import com.itic.appbase.framework.utils.configuration.PropertyHelper;

/**
 * 有模板导出excel
 * <p>
 * Company: itic
 * </p>
 * 
 * @author: shijun
 * @date: 2015年6月1日 下午2:11:45
 * @version: V1.0
 */
public class ExportExcelWithTemplet extends ExportExcel {

    @Override
    protected void exportAutoExcel(Map<String, Object> mapConfig,
            HttpServletRequest request, OutputStream outputStream) {
        
        if (null != mapConfig && !mapConfig.isEmpty() && null != mapConfig.get("bzmc")) {
            // 读取导出excel的数据
            String bzmc = String.valueOf(mapConfig.get("bzmc"));// 获取备注名称
            List<?> dataList = null == mapConfig.get("dataList") ? null 
                    : (List<?>) mapConfig.get("dataList"); // 获取数据信息
            // 根据备注名称获取properties文件配置信息
            // 获取导出配置id编号
            String id = PropertyHelper.getString(bzmc + ".id");
            // 获取导出字段信息
            String fieldsString = PropertyHelper.getString(bzmc + ".fields");
            // 获取数据在excel开始加载的行和列
            String xy = PropertyHelper.getString(bzmc + ".xy");
            // 获取模板文件路径
            String path = PropertyHelper.getString(bzmc + ".templatePath");
            log.info("id:" + id + ",templatePath:" + path + ",fields:"
                    + fieldsString + ",xy:" + xy);
            
            String[] fields = fieldsString.split(",");
            String absolutePath = request.getSession().getServletContext().getRealPath("/");
            String templatePath = absolutePath + "static/template/excelExport/" + path;// 获取模板文件绝对路径
            int startRow = Integer.parseInt(xy.substring(0, xy.indexOf(",")));// 开始行
            int startColumn = Integer.parseInt(xy.substring( xy.indexOf(",") + 1, xy.length()));// 开始列
            
            // 加载数据到Excel模板
            loadDataOnExcel(dataList, fields, templatePath, startRow,
                    startColumn, outputStream);
        }
    }

    /**
     * 加载数据到Excel模板
     * 
     * @param dataList 数据列表
     * @param fields 加载数据字段
     * @param templatePath Excel模板
     * @param startRow 开始行
     * @param startColumn  开始列
     * @param outputStream 输出流
     */
    private void loadDataOnExcel(List<?> dataList, String[] fields, String templatePath, int startRow, int startColumn,
            OutputStream outputStream) {
        HSSFWorkbook workBook = null;
        try {
            FileInputStream in = new FileInputStream(new File(templatePath));
            workBook = new HSSFWorkbook(in);
            int sheetNum = 0;// 所需工作表的数量
            if (null != dataList && !dataList.isEmpty()) {
                sheetNum = (int) Math.ceil((double) dataList.size() / 60000);// 一个工作表最大容量为60000
            }
            sheetNum = sheetNum == 0 ? 1 : sheetNum;
            // 设置单元格样式
            HSSFCellStyle cellStyle = PoiHelper.createCellStyle(workBook,
                    PoiHelper.creatFont(workBook));
            // 加载数据
            int dataListIndex = 0;// 加载数据坐标
            // 遍历工作表
            for (int i = 0; i < sheetNum; i++) {
                int startRowIndex = startRow;// 开始行坐标
                HSSFSheet sheet = workBook.getSheetAt(i);// 获取模板中的工作表
                if (null == sheet) {
                    sheet = PoiHelper.createSheet(workBook);
                }
                HSSFRow row = null;
                // 遍历数据
                for (int j = dataListIndex; j < dataList.size(); j++) {
                    Object obj = dataList.get(j);
                    row = PoiHelper.createRow(sheet, startRowIndex);// 创建行
                    HSSFCell cell = null;
                    for (int m = 0; m < fields.length; m++) {// 遍历字段
                        Object value = ReflectHelper.getValueByFieldName(obj, fields[m]);
                        cell = PoiHelper.createCell(row, m + startColumn);// 创建列
                        // 单元格赋值并添加样式
                        PoiHelper.setCellValue(cell, null == value ? "" : value, cellStyle);
                    }
                    dataListIndex++;
                    startRowIndex++;
                    // 如果到一张表的最大容量，则获取下一张工作表
                    if (startRowIndex != 0 && startRowIndex % 60000 == 0) {
                        break;
                    }
                }
            }
            workBook.write(outputStream);
        } catch (FileNotFoundException e) {
            log.info("IO异常");
        } catch (IOException e) {
            log.info("获取工作薄对象失败");
        } finally {
            if (workBook != null) {
                try {
                    workBook.close();
                } catch (IOException e) {
                    log.info("工作薄关闭失败");
                }
            }
        }
    }
}
